

module debounce(
    input        sys_clk   ,
    input        sys_rst_n ,

    input        key       ,   //澶栭儴杈撳叆鐨勬寜閿€�
    output  reg  key_pulse    //鎸夐敭娑堟姈鍚庣殑鍊�
);

//parameter define
parameter  CNT_MAX = 20'd100_0000;    //娑堟姈鏃堕棿20ms

//reg define
reg [19:0] 	cnt ;
reg        	key_d0;            //灏嗘寜閿俊鍙峰欢杩熶竴涓椂閽熷懆鏈�
reg        	key_d1;            //灏嗘寜閿俊鍙峰欢杩熶袱涓椂閽熷懆鏈�

reg			key_filter;
reg 		key_filter_d1;

//*****************************************************
//**                    main code
//*****************************************************

//瀵规寜閿鍙ｇ殑鏁版嵁寤惰繜涓や釜鏃堕挓鍛ㄦ湡
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) begin
        key_d0 <= 1'b1;
        key_d1 <= 1'b1;
    end
    else begin
        key_d0 <= key;
        key_d1 <= key_d0;
    end 
end

//鎸夐敭鍊兼秷鎶�
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) 
        cnt <= 20'd0;
    else begin
        if(key_d1 != key_d0)    //妫€娴嬪埌鎸夐敭鐘舵€佸彂鐢熷彉鍖�
            cnt <= CNT_MAX;     //鍒欏皢璁℃暟鍣ㄧ疆涓�20'd100_0000锛�
                                //鍗冲欢鏃�100_0000 * 20ns(1s/50MHz) = 20ms
        else begin              //濡傛灉褰撳墠鎸夐敭鍊煎拰鍓嶄竴涓寜閿€间竴鏍凤紝鍗虫寜閿病鏈夊彂鐢熷彉鍖�
            if(cnt > 20'd0)     //鍒欒鏁板櫒閫掑噺鍒�0
                cnt <= cnt - 1'b1;  
            else
                cnt <= 20'd0;
        end
    end
end

//灏嗘秷鎶栧悗鐨勬渶缁堢殑鎸夐敭鍊奸€佸嚭鍘�
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        key_filter <= 1'b1;
	//鍦ㄨ鏁板櫒閫掑噺鍒�1鏃堕€佸嚭鎸夐敭鍊�
    else if(cnt == 20'd1) 
		key_filter <= key_d1;
    else
		key_filter <= key_filter;
end

always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        key_filter_d1 <= 1'b1;
	//鍦ㄨ鏁板櫒閫掑噺鍒�1鏃堕€佸嚭鎸夐敭鍊�
    else
		key_filter_d1 <= key_filter;
end

always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        key_pulse <= 1'b0;
	//鍦ㄨ鏁板櫒閫掑噺鍒�1鏃堕€佸嚭鎸夐敭鍊�
    else
		key_pulse <= !key_filter&key_filter_d1;
end

endmodule

